#include "ws_data.h"
#include <stdio.h>
#include "pack.h"
#include "ota.h"
#include "log.h"
#include <pthread.h>
#include "mqtt_task.h"

static pthread_mutex_t     ws_data_mutex;

static int                  pws_control = FIRMWARE_INFO_NONE;

void ws_data_init()
{
    pthread_mutex_init(&ws_data_mutex, NULL);
}

void ws_reboot()
{
    pthread_mutex_lock(&ws_data_mutex);

    pws_control = FIRMWARE_INFO_REBOOT;

    pthread_mutex_unlock(&ws_data_mutex);
}

void ws_fwconfirm()
{
    pthread_mutex_lock(&ws_data_mutex);

    pws_control = FIRMWARE_INFO_CONFIRM;

    pthread_mutex_unlock(&ws_data_mutex);
}

void ws_boot2flash()
{
    pthread_mutex_lock(&ws_data_mutex);

    pws_control = FIRMWARE_INFO_BOOTFLASH;

    pthread_mutex_unlock(&ws_data_mutex);
}

void dataAckFill(WS_DATA_ACK* dataAck, uint8_t firmware_status)
{
    bool            newFirmware = false;

    dataAck->data = 0;

    // TODO:TEST  正常应该在这里清除加载到内存的估计，这样GetFirmwareInfo就不会有版本信息返回了。  =1的时候则忽略
    if (firmware_status < FIRMWARE_OTA) {
        // 判断是否有新版本，有则获取信息
        newFirmware = GetFirmwareInfo(&dataAck->firmware_info);
        if (newFirmware) {
            dataAck->data = FIRMWARE_INFO_NEW;
        }
    }

    if (firmware_status == FIRMWARE_SAME) {
        // log_print(LOG_INFO, "********************************************");
        FinishOTA();
        dataAck->data = FIRMWARE_INFO_CONFIRM;
    } else if (firmware_status == FIRMWARE_ERROR) {
        FinishOTA();
        dataAck->data = FIRMWARE_INFO_CONFIRM;
    }

    // 判断是否有重启的请求
    pthread_mutex_lock(&ws_data_mutex);

    switch (pws_control) {
        case FIRMWARE_INFO_REBOOT:
        case FIRMWARE_INFO_CONFIRM:
        case FIRMWARE_INFO_BOOTFLASH:
            dataAck->data = pws_control;
            pws_control = FIRMWARE_INFO_NONE;
            break;
    }

    pthread_mutex_unlock(&ws_data_mutex);
}

uint8_t cmd_Data(const WS_DATA* data, uint8_t no, uint8_t* sendBuffer)
{
    mqttPush(data);

    uint8_t         packSize;
    WS_DATA_ACK     dataAck;

    dataAckFill(&dataAck, data->firmware);

    packSize = packDataAck(&dataAck, CMD_DATA_ACK, no, sendBuffer, MAX_LORA_BUFFER_SIZE);

    return packSize;
}

uint8_t cmd_BeaconAck(const WS_LORA_STATUS* data, uint8_t no, uint8_t* sendBuffer)
{
    uint8_t         packSize;
    WS_DATA_ACK     dataAck;

    log_print(LOG_DEBUG, "Beacon remote No=%d  RSSI=%d, SNR=%d", data->no, data->rssi, data->snr);

    dataAckFill(&dataAck, FIRMWARE_NONE);

    packSize = packDataAck(&dataAck, CMD_BEACON_ACK, no, sendBuffer, MAX_LORA_BUFFER_SIZE);

    return packSize;
}